#pragma once

#include<thread>
#include<mutex>
#include <string>
#include <vector>
#include <functional>

struct Message
{
	std::string msg;
    std::function<void()> fun;
	bool quit{ false };

    Message() = default;
    Message(const std::string& str) : msg(str) {}
    Message(const std::string& str, bool quit) : msg(str), quit(quit) {}
};


class CycleLooper
{
public:
	static const int MAX_MESSAGE_COUNT = 5;

	CycleLooper();
	virtual ~CycleLooper();

	void enqueue(const Message& msg);
    void enqueueHead(const Message& msg);

    // 将msg 发送到异步线程执行，执行完成后才返回
    void handleSync(Message msg, bool immediately);

	void dequeue(Message& msg);

	bool isEmpty() const { return  count == 0; }
	bool isFull() const { return count == MAX_MESSAGE_COUNT; }

	void handle();
	void quit();

private:

    std::atomic_int32_t count;
	int head{};
	int tail{};
	Message queue[MAX_MESSAGE_COUNT];

    std::mutex guardCout; // 保证cout输出完一行后才能继续输出，防止多线程输出混乱

	std::condition_variable signal;
	std::mutex guard;

	std::thread worker;
	bool running{ false };
};

